'''
Created on 24-05-2012

@author: ahaw
'''
__author__ = 'ahaw'
from PyQt4 import QtGui
from Database import *
import string
from PyQt4.phonon import Phonon
class TreeWidget(QtGui.QTreeWidget):
    '''
    Klasa obsługująca drzewko, służące do filtrowania
    '''
    def __init__(self, *args):
        '''
        konstruktor z zainicjowanymi listami rodzaju,albumu,artystow,kolejki,playlist
        laczy ze zdarzeniami
        '''
        QtGui.QTreeWidget.__init__(self, *args)
        self.genreList = []
        self.artistList = []
        self.albumList = []
        self.fileList = []
        self.queue = []
        self.current = []
        self.playlists = []
        self.clicked.connect(self.onClick)
        TreeWidget.instance=self
    
    def addToQueue(self, file):
        '''
        Dodawanie pliku do listy kolejki
        '''
        if file not in TreeWidget.instance.queue:
            TreeWidget.instance.queue.append(file)
    def addToCurrent(self, file):
        '''
        Dodawanie pliku do listy playlisty roboczej
        '''
        if file not in TreeWidget.instance.current:
            TreeWidget.instance.current.append(file)   

    def onClick(self):
        '''
        Odswierzanie TableWidget na podstawie zaznaczenia w drzewku z TreeWidget
        '''
        item = self.currentItem()
        parent = self.currentItem().parent()
        if parent != None:
            TableWidget.instance.wymaz()
            if parent.text(0) == 'Playlists':
                if item.text(0) == 'Queue':
                    Database.cursor.execute('SELECT file,title,album,artist,genre,start,stop FROM baza WHERE file IN(%s)' % ("?," * len(TreeWidget.instance.queue))[:-1],TreeWidget.instance.queue)
                elif item.text(0) == 'Current':
                    Database.cursor.execute('SELECT file,title,album,artist,genre,start,stop FROM baza WHERE file IN(%s)' % ("?," * len(TreeWidget.instance.current))[:-1],TreeWidget.instance.current)
                elif item.text(0) == 'Saved playlists':
                    print ("playlists")
            elif parent.text(0) == 'Saved playlists':
                    print(Settings.instance.playlistsDirectory+  item.text(0))
                    
                    files = [line.strip() for line in open(Settings.instance.playlistsDirectory+ item.text(0))]
                    Database.cursor.execute('SELECT file,title,album,artist,genre,start,stop FROM baza WHERE file IN(%s)' % ("?," * len(files))[:-1],files)
               
                    print ("Files are:", files)
            elif parent.text(0) == 'Rodzaj':
                Database.cursor.execute('SELECT file,title,album,artist,genre,start,stop FROM baza WHERE genre LIKE "%'+item.text(0)+ '%"')                                                                             
            elif parent.text(0) == 'Wykonawca':
                Database.cursor.execute('SELECT file,title,album,artist,genre,start,stop FROM baza WHERE artist=?', [item.text(0)])
            elif parent.text(0) == 'Album':
                Database.cursor.execute('SELECT file,title,album,artist,genre,start,stop FROM baza WHERE album=?', [item.text(0)])
            else:
                pattern = ''
                while item.parent() != None:
                    pattern = '/' + item.text(0) + pattern
                    item = item.parent()
                pattern = '%' + pattern + '%'
                Database.cursor.execute('select file,title,album,artist,genre,start,stop FROM baza WHERE file LIKE ?', [pattern])
        TableWidget.instance.wypelnij()
    def readPlaylists(self):
        '''
        wczytywanie playlist
        '''
        if not os.path.exists(Settings.instance.playlistsDirectory):
                os.makedirs(Settings.instance.playlistsDirectory)
        dirList=os.listdir(Settings.instance.playlistsDirectory)
        for fname in dirList:
            QtGui.QTreeWidgetItem(self.playListTree.child(2), [fname])
            
    def refreshTreeValues(self):
        '''
        Tworzenie i odswierzanie drzewka katalogw,artystkow,albumow, etc.
        '''
        TreeWidget.instance.genreList=[]
        TreeWidget.instance.artistList =[]
        TreeWidget.instance.albumList =[]
        Database.cursor.execute('SELECT * FROM baza ORDER BY file')
        for row in Database.cursor:
            for each in row[4].split('/'):
                genre=each.strip()
                if genre not in self.genreList:
                    self.genreList.append(genre)
            if row[3] not in self.artistList:
                self.artistList.append(row[3])
            if row[2] not in self.albumList:
                self.albumList.append(row[2])
            if row[0] not in self.fileList:
                self.fileList.append(row[0])
        self.genreList.sort()
        self.albumList.sort()
        self.artistList.sort()
        self.fileList.sort()
        
        self.clear()
        
        self.playListTree = QtGui.QTreeWidgetItem(self, ['Playlists'])
        self.genreTree = QtGui.QTreeWidgetItem(self, ['Rodzaj'])        
        self.artistTree = QtGui.QTreeWidgetItem(self, ['Wykonawca'])        
        self.albumTree = QtGui.QTreeWidgetItem(self, ['Album'])        
        self.fileTree = QtGui.QTreeWidgetItem(self, ['Plik'])

        for playlist in ['Queue', 'Current','Saved playlists']:
            QtGui.QTreeWidgetItem(self.playListTree, [playlist])
        for genre in self.genreList:
            QtGui.QTreeWidgetItem(self.genreTree, [genre])
        for album in self.albumList:
            QtGui.QTreeWidgetItem(self.albumTree, [album])
        for artist in self.artistList:
            QtGui.QTreeWidgetItem(self.artistTree, [artist])
        for file in self.fileList:
            parent = self.fileTree
            location = file[1:].split('/')
            for each in location:
                if parent.childCount() == 0:
                    parent = QtGui.QTreeWidgetItem(parent, [each])
                elif parent.child(parent.childCount() - 1).text(0) == each:
                    parent = parent.child(parent.childCount() - 1)
                else:
                    parent = QtGui.QTreeWidgetItem(parent, [each])





class TableWidget(QtGui.QTableWidget):
    updateSignal = QtCore.pyqtSignal()
    def __init__(self, *args):
        '''
        Tworzenie TableWidget
        tworzenie naglowkow tabeli
        podlaczanie fukcji do zdarzen
        '''
        QtGui.QTableWidget.__init__(self, *args)
        self.doubleClicked.connect(self.play)
        self.setHorizontalHeaderLabels(['Sciezka', 'Tytuł', 'Album', 'Wykonawca', 'Rodzaj','Czas Startu', 'Czas Zakonczenia'])
        self.header = self.horizontalHeader()
        #self.header.sectionClicked.connect(self.markCollumn)
        self.header.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.header.customContextMenuRequested.connect(self.headerMenu)
        self.setSortingEnabled(True)
        TableWidget.instance=self
        
#####
#####    Rzeczy zwiazane z nagłówkiem
#####
    def headerMenu(self, pos):
        '''
        Tworzenie menu kontekstowego dla naglowka
        '''
        globalPos = self.mapToGlobal(pos)
        menu = QtGui.QMenu()
        showMenu = menu.addMenu('&Pokaz')
        hideMenu = menu.addMenu('&Schowaj')
        
        print ("FileWidget.HeaderMenu: przepisac")
        #hideShowFile = hideMenu.addAction('Hide current collumn')
        #hideShowFile.triggered.connect(lambda : self.headerHideCurrentCollumn(pos))
        if self.isColumnHidden(0):
            hideShowFileAction = showMenu.addAction('Pokaż scieżkę')
        else:
            hideShowFileAction = hideMenu.addAction('Ukryj scieżkę')
        if self.isColumnHidden(1):
            hideShowTitleAction = showMenu.addAction('Pokaż tytuł')
        else:
            hideShowTitleAction = hideMenu.addAction('Ukryj tytuł')
        if self.isColumnHidden(2):
            hideShowAlbumAction = showMenu.addAction('Pokaż album')
        else:
            hideShowAlbumAction = hideMenu.addAction('Ukryj album')
        if self.isColumnHidden(3):
            hideShowArtistAction = showMenu.addAction('Pokaż wykonawcę')
        else:
            hideShowArtistAction = hideMenu.addAction('Ukryj wykonawcę')    
        if self.isColumnHidden(4):
            hideShowGenreAction = showMenu.addAction('Pokaż rodzaj')
        else:
            hideShowGenreAction = hideMenu.addAction('Ukryj rodzaj')
            
        hideShowTitleAction.triggered.connect(self.hideShowTitleColumn)
        hideShowAlbumAction.triggered.connect(self.hideShowAlbumColumn)
        hideShowFileAction.triggered.connect(self.hideShowFileColumn)
        hideShowArtistAction.triggered.connect(self.hideShowArtistColumn)
        hideShowGenreAction.triggered.connect(self.hideShowGenreColumn)
        menu.exec_(globalPos)
    def hideShowFileColumn(self):
        '''
        chowanie/pokazywanie kolumny
        '''
        if self.header.isSectionHidden(0):
            self.header.showSection(0)
        else:
            self.header.hideSection(0)        
    def hideShowTitleColumn(self):
        '''
        chowanie/pokazywanie kolumny
        '''
        if self.header.isSectionHidden(1):
            self.header.showSection(1)
        else:
            self.header.hideSection(1)
    def hideShowAlbumColumn(self):
        '''
        chowanie/pokazywanie kolumny
        '''
        if self.header.isSectionHidden(2):
            self.header.showSection(2)
        else:
            self.header.hideSection(2)
    def hideShowArtistColumn(self):
        '''
        chowanie/pokazywanie kolumny
        '''
        if self.header.isSectionHidden(3):
            self.header.showSection(3)
        else:
            self.header.hideSection(3)
    def hideShowGenreColumn(self):
        '''
        chowanie/pokazywanie kolumny
        '''
        if self.header.isSectionHidden(4):
            self.header.showSection(4)
        else:
            self.header.hideSection(4)
            
    def headerHideCurrentCollumn(self, pos):
        '''
        chowanie obecnej
        '''
        self.header.hideSection(self.header.logicalIndexAt(pos))

    def markCollumn(self):
        print('markcollumn')

    def updateFileTag(self, t):
        '''
        Uaktualnianie tagu pliku
        '''
        tag = stagger.read_tag(t[0])
        tag.title = t[1]
        tag.album = t[2]
        tag.artist = t[3]
        tag.genre = t[4]
        tag.write()

    def cellChanged(self, row, col):
        '''
        uaktualnianie tagu oraz wpisu w bazie zmodyfikowanych plikow w tablewidget
        '''
        #p=file,title,artist,album,genre,start,stop,
        p = self.item(row, 0).text(), self.item(row, 1).text(), self.item(row, 2).text(), self.item(row, 3).text(), self.item(row, 4).text(),self.item(row, 5).text(),self.item(row, 6).text()
        Database.removeFromDatabase(Database.instance,p[0])
        self.updateFileTag(p)
        Database.addToDatabase(Database.instance,p[0],p[5],p[6])
        #self.wypelnijWszystko()
        Database.instance.connection.commit()

    def contextMenuEvent(self, event):
        '''
        Menu kontekstowe tableWidget umozliwiajace dodawanie pliow do playlist,filtrowanie, etc.
        '''
        menu = QtGui.QMenu(self)
        playAction = menu.addAction('Play')
        playAction.triggered.connect(self.play)
        
        addToQueueAction = menu.addAction('Add to Queue')
        addToQueueAction.triggered.connect(self.addToQueue)
        
        addToCurrentAction = menu.addAction('Add to Current')
        addToCurrentAction.triggered.connect(self.addToCurrent)
        
        rmAction = menu.addAction('Usun')
        rmAction.triggered.connect(self.removeFromListAction)
        
        filterAction = menu.addMenu('Filter')
        filterGenre = filterAction.addAction('Genre')
        filterGenre.triggered.connect(self.filterGenreAction)
        filterAlbum = filterAction.addAction('Album')
        filterAlbum.triggered.connect(self.filterAlbumAction)
        filterArtist = filterAction.addAction('Artist')
        filterArtist.triggered.connect(self.filterArtistAction)
        
        
        menu.exec_(event.globalPos())

    def removeFromListAction(self):
        fileToRemove=self.item(self.currentRow(), 0).text()
        TreeWidget.instance.queue.remove(fileToRemove)
        TreeWidget.onClick(TreeWidget.instance)
    def filterAlbumAction(self):
        '''
        Filtr umozliwiajacy wyswietlenie utworow z jednego albumu
        '''
        tmp= (ListWidget.album.findItems(self.item(self.currentRow(), 2).text(),QtCore.Qt.MatchExactly)[0])        
        ListWidget.album.setCurrentItem(tmp)
        ListWidget.currentItemChanged(self)
    def filterArtistAction(self):
        '''
        Filtr umozliwiajacy wyswietlenie utworow z jednego albumu
        '''
        tmp= (ListWidget.artist.findItems(self.item(self.currentRow(), 3).text(),QtCore.Qt.MatchExactly)[0])        
        ListWidget.artist.setCurrentItem(tmp)
        ListWidget.currentItemChanged(self)
        #print(self.item(self.currentRow(), 0).text())
    def filterGenreAction(self):
        '''
        Filtr umozliwiajacy wyswietlenie utworow z jednego albumu
        '''
        tmp= (ListWidget.genre.findItems(self.item(self.currentRow(), 4).text(),QtCore.Qt.MatchExactly)[0])        
        ListWidget.genre.setCurrentItem(tmp)
        ListWidget.currentItemChanged(self)
        

    def addToQueue(self):
        '''
        Dodawanie pliku do kolejki
        '''
        TreeWidget.instance.addToQueue(self.item(self.currentRow(), 0).text())
    
    def addToCurrent(self):
        '''
        Dodawanie pliku do kolejki
        '''
        TreeWidget.instance.addToCurrent(self.item(self.currentRow(), 0).text())

    def wymaz(self):
        '''
        Wymazywanie tablewidget
        '''
        rowCount = self.rowCount()
        for row in range(self.rowCount()):
            rowCount = rowCount - 1
            self.removeRow(rowCount)

    def play(self):
        '''
        wlaczenie odtwarzania gdy nie w trybie edytowania
        '''
        if not Settings.editState:
            self.audioPlay.changeFile(self.item(self.currentRow(), 0).text(),self.item(self.currentRow(), 5).text(),self.item(self.currentRow(), 6).text())
            
    def dodaj(self, krotka):
        print("TableWidget.dodaj")
        '''
        dodawanie plikow do tablewidget
        '''
        self.disconnect(self, QtCore.SIGNAL('cellChanged(int, int)'), self.cellChanged)
        self.insertRow(self.rowCount())
        n = self.rowCount() - 1
        m = 0
        for item in krotka:
            self.setItem(n, m, QtGui.QTableWidgetItem(item))
            m += 1
        self.connect(self, QtCore.SIGNAL('cellChanged(int, int)'), self.cellChanged)
       
    def wypelnij(self):
        '''
        wypelnia tablewidget informacjami z bazy danych 
        '''
        self.setSortingEnabled(False)        
        self.wymaz()
        self.disconnect(self, QtCore.SIGNAL('cellChanged(int, int)'), self.cellChanged)
        n = 0
        for row in Database.cursor:
            m = 0
            self.insertRow(self.rowCount())
            for item in row:
                self.setItem(n, m, QtGui.QTableWidgetItem(item))
                m += 1
            n += 1
        self.connect(self, QtCore.SIGNAL('cellChanged(int, int)'), self.cellChanged)
        self.setSortingEnabled(True)
    def edit(self, index, trigger, event):
        '''
        Zwraca wartosc true gdy w trybie edycji
        '''
        if Settings.editState != False and QtGui.QTableWidget.edit(self, index, trigger, event):
            return True
        return False

class ListWidget(QtGui.QListWidget):

    def __init__(self, listType):
        '''
        Konstruktor ten: 
        Tworzy odpowiedni typ widzetu z zaleznosci od parametru (genre,artist,album)
        dodaje go do zmiennych klasowych
        wypelnia go
        laczy ze zdarzeniami
        '''
        super(ListWidget, self).__init__()
        self.itemActivated.connect(self. currentItemChanged  )
        self.type = listType
        if self.type=='genre':
            ListWidget.genre=self
        elif self.type=='artist':
            ListWidget.artist=self
        elif self.type=='album':
            ListWidget.album=self
        ListWidget.wypelnij=self.wypelnij
   

    def currentItemChanged(self):
        '''
        Filtruje na podstawie utworzonych widzetow.
        odpytuje baze danych
        wypenia tableWidget
        '''
        QUERY = 'SELECT file,title,album,artist,genre,start,stop FROM baza WHERE '
        genre = ListWidget.genre.currentItem().text()
        album = ListWidget.album.currentItem().text()
        artist = ListWidget.artist.currentItem().text()
        
        if genre == 'Wszystkie':
            QUERY += 'genre=genre and '
        else:
            QUERY += 'genre LIKE "%' + genre + '%" and '
        
        if album == 'Wszystkie':
            QUERY += 'album=album and '
        else:
            QUERY += 'album="' + album + '" and '
        if artist == 'Wszystkie':
            QUERY += 'artist=artist '
        else:
            QUERY += 'artist="' + artist + '" '
        print (QUERY)
        Database.cursor.execute(QUERY)        
        TableWidget.instance.wypelnij()

    def wypelnij(self):
        '''
        Wypelnia widzety elementami odpowiednimi do typu widzetu
        
        '''
        ListWidget.genre.clear()
        ListWidget.artist.clear()
        ListWidget.album.clear()
        
        ListWidget.album.addItem('Wszystkie')
        ListWidget.genre.addItem('Wszystkie')
        ListWidget.artist.addItem('Wszystkie')
        
        for i in TreeWidget.instance.genreList:
                ListWidget.genre.addItem(i)
        
        for i in TreeWidget.instance.artistList:
            ListWidget.artist.addItem(i)
            
        for i in TreeWidget.instance.albumList:
            ListWidget.album.addItem(i)
        
        ListWidget.album.setCurrentRow(0)        
        ListWidget.genre.setCurrentRow(0)
        ListWidget.artist.setCurrentRow(0)

class AudioPlayer(QtGui.QWidget):

    def __init__(self,*args):
        QtGui.QWidget.__init__(self, *args)
        '''
        Tworzenie layoutu widżetu, dodawanie przyciskow, suwaków i tworzenie MediaObject
        wraz z ustawieniami
        polaczenia ze zdarzeniami
        '''
        #self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)          
        
        self.layout = QtGui.QHBoxLayout(self)
        #self.mediaObject = Phonon.createPlayer(Phonon.MusicCategory, Phonon.MediaSource(''))
         
        self.mediaObject = Phonon.MediaObject(self)
        self.audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
        Phonon.createPath(self.mediaObject, self.audioOutput)

        self.mediaObject.connect
        self.mediaObject.setTickInterval(1000)
        self.mediaObject.tick.connect(self.tock) 
        self.mediaObject.stateChanged.connect(self.stateChanged)
        self.mediaObject.seekableChanged.connect(self.seekableChanged)
        self.mediaObject.aboutToFinish.connect(self.aboutToFinish)
        self.slider = Phonon.SeekSlider(self.mediaObject, self)
        
        self.play_pause = QtGui.QPushButton("Play",self)
        self.play_pause.clicked.connect(self.playClicked)
        self.play_pause.setIcon(QtGui.QIcon('icons/oxygen/gtk-media-play.png'))
        self.startFromButton = QtGui.QPushButton("startFrom",self)
        self.startFromButton.clicked.connect(self.startFrom)
        
        #self.stopOnButton = QtGui.QPushButton("stopOn",self)
        #self.stopOnButton.clicked.connect(self.stopOn)
        
        self.status = QtGui.QLabel(self)
        #self.status.setAlignment(QtCore.Qt.AlignRight |QtCore.Qt.AlignVCenter)
        self.layout.addWidget(self.play_pause)
        self.layout.addWidget(self.startFromButton)
        #self.layout.addWidget(self.stopOnButton)
        self.layout.addWidget(self.slider)
        self.layout.addWidget(self.status)
        AudioPlayer.instance=self

    def changeFile(self, file,startTime,stopTime):
        '''
        Zmiana obecnie odtwarzanego pliku, wraz z stopTime i startTime, oraz rozpoczecie odtwarzania
        '''
        self.startTime=int(startTime)
        self.stopTime=int(stopTime)
        self.file=file
        self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
        self.mediaObject.play()
                

    def playClicked(self):
        '''
        Zatrzymywanie/wznawiania odtwarzania utworu
        '''
        if self.mediaObject.state() == Phonon.PlayingState:
            self.mediaObject.pause()
        else:
            self.mediaObject.play()
    def stateChanged(self, new, old):
        '''
        zmienianie ikonki przy zmianie stanu odtwarzania
        '''
        if new == Phonon.PlayingState:
            self.play_pause.setIcon(QtGui.QIcon('icons/oxygen/gtk-media-pause.png'))
        else:
            self.play_pause.setIcon(QtGui.QIcon('icons/oxygen/gtk-media-play.png'))
            
    def startFrom(self):
        '''
        Funkcja zmnieniajaca wartosc startTime
        '''

        QUERY ='SELECT file,album,artist,genre,start,stop FROM baza WHERE file=?'
        Database.cursor.execute(QUERY, [self.file])
        file=list(Database.cursor.fetchone())
        file[4]=self.mediaObject.currentTime()/(1000)
        Database.removeFromDatabase(Database.instance,self.file)
        Database.addToDatabase(Database.instance, file[0], file[4], file[5])

    def stopOn(self):
        '''
        Funkcja zmnieniajaca wartosc stopTime
        '''
        print (self.mediaObject.currentTime()/(1000))
        QUERY ='SELECT file,album,artist,genre,start,stop FROM baza WHERE file=?'
        Database.cursor.execute(QUERY, [self.file])
        file=list(Database.cursor.fetchone())
        file[5]=self.mediaObject.currentTime()/(1000)
        Database.removeFromDatabase(Database.instance,self.file)
        Database.addToDatabase(Database.instance, file[0], file[4], file[5])

    def seekableChanged(self):
        '''
        Rozpoczynanie utworu od wybranego fragmentu (np ominiecie ciszy)
        '''
        if self.startTime>0 and self.mediaObject.isSeekable():
            print ('Changing seek')
            self.mediaObject.seek(self.startTime*1000)
    def tock(self):
        '''
        Aktualizacja obecnego czasu oraz maksymalnego czasu odtwarzania utworu
        Zatrzymanie odtwarzania gdy zostanie przekroczony znacznik STOP
        '''
        min = self.mediaObject.currentTime()/(1000*60)
        sec = self.mediaObject.currentTime()/1000 % 60
        tmin = self.mediaObject.totalTime()/(1000*60)
        tsec = self.mediaObject.totalTime()/1000 % 60
        self.status.setText('%02d:%02d/%02d:%02d' % (min,sec,tmin,tsec))
        if self.stopTime>0 and (self.stopTime*1000)<self.mediaObject.currentTime():
            self.mediaObject.clear()
            if len(TreeWidget.instance.queue):
                print ('tock')
                QUERY ='SELECT start,stop FROM baza WHERE file=?'
                Database.cursor.execute(QUERY, [TreeWidget.instance.queue[0]])
                times=Database.cursor.fetchone()
                self.startTime=int(times[0])
                self.stopTime=int(times[1])
                self.aboutToFinish()
                self.mediaObject.play()
            
    def aboutToFinish(self):
        '''
        dodaje do kolejki mediaobject plik
        '''
        if len(TreeWidget.instance.queue):
            self.file = TreeWidget.instance.queue.pop(0)
            self.mediaObject.enqueue(Phonon.MediaSource(Phonon.MediaSource(self.file)))